<?php 
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。
//  JCAT 由中国团队开发维护，是一个国际性的项目。
//  正在使用的这个版本是：0.3.2 / SVN信息：$Id: class.JCAT_Document.php 1119 2008-10-25 03:55:26Z alee $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [HTTP下载] http://jcat.JeCat.cn/download
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.cn/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.cn/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/


class JCAT_RequestDispatcher 
{
	/**
	 * Description
	 *
	 * @access	public
	 * @static
	 * @return	JCAT_ResultDispatcher
	 */
	static public function GetGlobalInstance()
	{
		if( !self::$aGlobalInstance )
		{
			self::$aGlobalInstance = new JCAT_RequestDispatcher() ;
		}
		return self::$aGlobalInstance ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sAlias
	 * @param	$sControllerClass
	 * @return	void
	 */
	public function RegisterControllerAlias($sAlias,$sControllerClass)
	{
		if( $sAlias!=$sControllerClass and JCAT_Global::HasImplementedTo($sAlias,'JCAT_IHTTPPublicController') )
		{
			throw new JCAT_Exception(JCAT_Language::SentenceEx(
				'无法注册控制器别名：%s，已经存在同名的控制器类。'
				, 'JCAT', null
				, $sAlias
			)) ;
		}
		
		$this->arrControllerAliasies[$sAlias] = $sControllerClass ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sAlias
	 * @return	string
	 */
	public function GetControllerClassByAlias($sAlias)
	{
		return isset($this->arrControllerAliasies[$sAlias])?
						$this->arrControllerAliasies[$sAlias] : null ;
	}
	
	
	/**
	 * set a default controller, if request has no specified controller, use this
	 *
	 * @access	public
	 * @param	$sDefaultController
	 * @return	void
	 */
	public function SetDefaultController($sDefaultController)
	{
		JCAT_ASSERT::ASSERT_ISTHESE($sDefaultController,array('JCAT_IController','null')
				, JCAT_Language::SentenceEx('%s::%s 参数 $sDefaultController 必须实现 JCAT_IController 接口。', 'JCAT', null
				, __CLASS__
				, __FUNCTION__)
		) ;

		$this->sDefaultController = $sDefaultController ;
	}
	
	/**
	 * respond the user request
	 *
	 * @access	public
	 * @return	void
	 */
	public function Respond()
	{
		// get user request
		$aRequest = JCAT_Request::GetGlobalInstance() ;
		
		// get controller which user request
		if( !$sControllerName = $aRequest->GetRequestController() )
		{
			if( $this->sDefaultController )
			{
				$sControllerName = $this->sDefaultController ;
			}
		
			else 
			{
				throw new JCAT_Exception(JCAT_Language::SentenceEx(
					'当前请求既没有指定控制器，也没有定义缺省控制器。'
					, 'JCAT', null
				)) ;
			}
		}
		
		// get controller class by alias
		$sControllerNameByAlias = $this->GetControllerClassByAlias($sControllerName) ;
		if($sControllerNameByAlias)
		{
			$sControllerName = $sControllerNameByAlias ;
		}

		// check if valid
		JCAT_ASSERT::ASSERT_ISCLASS($sControllerName,array('JCAT_IController')
					, JCAT_Language::SentenceEx('正在请求一个未知的控制器：%s','JCAT',null,$sControllerName));

		// run it
		$this->RunController($sControllerName) ;
	}
	
	/**
	 * run a controller
	 *
	 * @access	public
	 * @param	$sControllerName
	 * @return	void
	 */
	public function RunController($sControllerName,$bAsTop=true)
	{
		if( JCAT_Request::IsHTTPRequest() and !JCAT_Global::HasImplementedTo($sControllerName,'JCAT_IHTTPPublicController') )
		{
			throw new JCAT_Exception(JCAT_Language::SentenceEx(
				"正在请求的控制器(%s)没有实现 JCAT_IHTTPPublicController 接口，无法通过 HTTP 直接访问。"
				, 'JCAT', null
				, $sControllerName
			)) ;
		}
		
		// 创建控制器 
		$aController = new $sControllerName() ;
		
		if( $bAsTop and JCAT_Global::HasImplementedTo($sControllerName,'JCAT_IControllerSetDataAutomatically') )
		{
			$aRequest = JCAT_Request::GetGlobalInstance() ;
			$aController->SetDatasFromUserRequest($aRequest) ;
		}
		
		$aController->MainRun() ;
	}
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @static
	 * @var		JCAT_ResultDispatcher
	 */
	static private $aGlobalInstance ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		array
	 */
	private $arrControllerAliasies = array() ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		string
	 */
	private $sDefaultController ;
}

?>